package com.spring.demo.init.db;

import java.beans.PropertyVetoException;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.support.TransactionTemplate;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * jpa 数据库配置
 * 
 * @author sean
 * 
 */
@Configuration
@PropertySource({ "classpath:db/jdbcTemplate.properties" })
@EnableTransactionManagement
public class JdbcTemplateDatabaseConfig extends EmbeddedDataSource {

	// jdbc config
	@Value("${jdbc.driverClass}")
	private String DB_DRIVER_CLASS_NAME;

	@Value("${jdbc.username}")
	private String DB_USERNAME;

	@Value("${jdbc.password}")
	private String DB_PASSWORD;

	@Value("${jdbc.url}")
	private String DB_URL;

	// c3p0 config
	@Value("${jdbc.maxPoolSize}")
	private int C3P0_MAXPOOLSIZE;
	@Value("${jdbc.minPoolSize}")
	private int C3P0_MINPOOLSIZE;
	@Value("${jdbc.maxStatements}")
	private int C3P0_MAXSTATEMENTS;
	@Value("${jdbc.testConnection}")
	private boolean C3P0_TESTCONNECTION;

	// hibernate properties
	@Value("${hibernate.dialect}")
	private String HIBERNATE_DIALECT;

	@Value("${hibernate.show_sql}")
	private String HIBERNATE_SHOW_SQL;

	@Value("${hibernate.hbm2ddl.auto}")
	private String HIBERNATE_HBM2DDL_AUTO;

	@Bean(name = "jdbcDataSource")
	public DataSource jdbcDataSource() throws PropertyVetoException {
		ComboPooledDataSource c3p0DataSource = new ComboPooledDataSource();
		c3p0DataSource.setDriverClass(DB_DRIVER_CLASS_NAME);
		c3p0DataSource.setJdbcUrl(DB_URL);
		c3p0DataSource.setUser(DB_USERNAME);
		c3p0DataSource.setPassword(DB_PASSWORD);
		c3p0DataSource.setMaxPoolSize(C3P0_MAXPOOLSIZE);
		c3p0DataSource.setMinPoolSize(C3P0_MINPOOLSIZE);
		c3p0DataSource.setMaxStatements(C3P0_MAXSTATEMENTS);
		c3p0DataSource.setTestConnectionOnCheckout(C3P0_TESTCONNECTION);

		return c3p0DataSource;
	}

	@Bean(name = "jdbcTemplate")
	@Autowired
	public JdbcTemplate jdbcTemplate(
			@Qualifier("jdbcDataSource") DataSource dataSource) {
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

		return jdbcTemplate;
	}

	@Bean(name = "jdbcTransactionManager")
	@Autowired
	public PlatformTransactionManager transactionManager(
			@Qualifier("embeddedDataSource") DataSource dataSource) {
		DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(
				dataSource);

		return transactionManager;
	}

	@Bean(name = "jdbcTransactionTemplate")
	@Autowired
	public TransactionTemplate transactionTemplate(
			@Qualifier("jdbcTransactionManager") PlatformTransactionManager transactionManager) {
		TransactionTemplate transactionTemplate = new TransactionTemplate(
				transactionManager);
		return transactionTemplate;
	}

	@Bean
	public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
		return new PropertySourcesPlaceholderConfigurer();
	}
}
